using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Identity.Application.Contracts.Common;
using Identity.Application.Contracts.Services;
using Microsoft.IdentityModel.Tokens;

namespace Identity.Infrastructure.Persistence.IdentityService
{
    public class TokenService : ITokenService
    {
        private readonly JwtOptions _options;
        private readonly byte[] _secretKeyBytes;

        public TokenService(JwtOptions options)
        {
            _options = options;
            _secretKeyBytes = Encoding.UTF8.GetBytes(_options.SecretKey);
        }

        public string GenerateAccessToken(IEnumerable<Claim> claims)
        {
            return GenerateToken(claims, _options.AccessTokenExpirationMinutes);
        }

        public string GenerateTemporaryToken(IEnumerable<Claim> claims)
        {
            return GenerateToken(claims, _options.TempTokenExpirationMinutes);
        }

        private string GenerateToken(IEnumerable<Claim> claims, int expireMinutes)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = new SymmetricSecurityKey(_secretKeyBytes);
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.UtcNow.AddMinutes(expireMinutes),
                Issuer = _options.Issuer,
                Audience = _options.Audience,
                SigningCredentials = creds
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }

        public ClaimsPrincipal? ValidateToken(string token, bool validateLifetime = true)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var validationParams = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateIssuerSigningKey = true,
                ValidateLifetime = validateLifetime,
                ValidIssuer = _options.Issuer,
                ValidAudience = _options.Audience,
                IssuerSigningKey = new SymmetricSecurityKey(_secretKeyBytes),
                ClockSkew = TimeSpan.Zero // 去掉默认的 5 分钟宽限
            };

            try
            {
                var principal = tokenHandler.ValidateToken(token, validationParams, out _);
                return principal;
            }
            catch
            {
                return null; // 验证失败
            }
        }
    }
}